#include "sdk.h"
#include <wx/filedlg.h>
#include "filefilters.h"

M_Code_Workspace::M_Code_Workspace( const wxString& filename ) :
  m_IsOK( true ),
  m_IsDefault( true ),
  m_Modified( false ),
  m_Filename( DEFAULT_WORKSPACE ),
  m_Title( _T( "默认工作区" ) ),
  m_PreferredTargetName() {
  if( filename.Matches( DEFAULT_WORKSPACE ) || filename.IsEmpty() ) {
    wxString tmp = ConfigManager::GetConfigFolder();
    if( !wxDirExists( tmp ) ) {
      wxMkdir( tmp, 0755 );
    }
    tmp << wxFILE_SEP_PATH << DEFAULT_WORKSPACE;
    m_Filename = tmp;
  } else {
    m_Filename = filename;
    m_IsDefault = false;
  }
  if( !filename.IsEmpty() ) {
    Load();
  }
}

M_Code_Workspace::~M_Code_Workspace() {
}

void M_Code_Workspace::Load() {
  wxString fname = m_Filename.GetFullPath();
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "正在加载工作区 \"%s\"" ), fname.wx_str() ) );
  if( !m_Filename.FileExists() ) {
    Manager::Get()->GetLogManager()->DebugLog( _T( "文件不存在." ) );
    if( !m_IsDefault ) {
      wxString msg;
      msg.Printf( _T( "工作空间 '%s' 不存在..." ), fname.c_str() );
      msging( msg, _T( "错误" ), wxOK | wxCENTRE | wxICON_ERROR );
      m_IsOK = false;
      return;
    }
  }
  if( FileTypeOf( fname ) == ftm_Code_Workspace ) {
    IBaseWorkspaceLoader* pWsp = new WorkspaceLoader;
    wxString Title;
    m_IsOK = pWsp && ( pWsp->Open( fname, Title ) || m_IsDefault );
    if( !Title.IsEmpty() ) {
      m_Title = Title;
    }
    delete pWsp;
  }
  LoadLayout();
  m_Filename.SetExt( FileFilters::M_WORKSPACE_EXT );
  SetModified( false );
}

bool M_Code_Workspace::Save( bool force ) {
  if( m_Filename.GetFullPath().IsEmpty() ) {
    return SaveAs( _T( "" ) );
  }
  SaveLayout();
  if( !force && !m_Modified ) {
    return true;
  }
  Manager::Get()->GetLogManager()->Log( F( _T( "正在保存工作区\"%s\"" ), m_Filename.GetFullPath().wx_str() ) );
  WorkspaceLoader wsp;
  bool ret = wsp.Save( m_Title, m_Filename.GetFullPath() );
  SetModified( !ret );
  if( !ret ) {
    msging( _T( "无法保存工作区 " ) + m_Filename.GetFullPath() + _T( "\n(可能文件有写保护?)" ), _T( "警告" ), wxICON_WARNING );
  }
  return ret;
}

bool M_Code_Workspace::SaveAs( M_Code_unused const wxString& filename ) {
  wxFileDialog dlg( Manager::Get()->GetAppWindow(), _T( "保存工作区" ), m_Filename.GetPath(),
                    m_Filename.GetFullName(), FileFilters::GetFilterString( _T( '.' ) + FileFilters::M_WORKSPACE_EXT ),
                    wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
  PlaceWindow( &dlg );
  if( dlg.ShowModal() != wxID_OK ) {
    return false;
  }
  m_Filename = dlg.GetPath();
  if( m_Filename.GetExt() == wxEmptyString ) {
    m_Filename.SetExt( _T( "workspace" ) );
  }
  if( m_Filename.GetFullName().Matches( DEFAULT_WORKSPACE ) ) {
    m_IsDefault = true;
  } else {
    m_IsDefault = false;
  }
  return Save( true );
}

void M_Code_Workspace::SetTitle( const wxString& title ) {
  m_Title = title;
  SetModified( true );
}

void M_Code_Workspace::SetModified( bool modified ) {
  m_Modified = modified;
}

void M_Code_Workspace::SetPreferredTarget( const wxString &target ) {
  if( !target.IsEmpty() ) {
    m_PreferredTargetName = target;
  }
}

wxString M_Code_Workspace::GetPreferredTarget() const {
  return m_PreferredTargetName;
}

void M_Code_Workspace::ActiveProjectChanged() {
  SaveLayout();
}

bool M_Code_Workspace::SaveLayout() {
  LogManager *log = Manager::Get()->GetLogManager();
  WorkspaceLoader wsl;
  wxFileName fn( m_Filename );
  fn.SetExt( _T( "workspace.layout" ) );
  log->Log( F( _T( "保存工作区布局 \"%s\"" ), fn.GetFullPath().wx_str() ) );
  const bool rc = wsl.SaveLayout( fn.GetFullPath() );
  if( !rc ) {
    log->Log( F( _T( "无法保存工作区布局 \"%s\"" ), fn.GetFullPath().wx_str() ) );
  }
  return rc;
}

bool M_Code_Workspace::LoadLayout() {
  LogManager *log = Manager::Get()->GetLogManager();
  WorkspaceLoader wsl;
  wxFileName fn( m_Filename );
  fn.SetExt( _T( "workspace.layout" ) );
  bool rc = false;
  if( fn.FileExists() ) {
    log->Log( F( _T( "加载工作区布局 \"%s\"" ), fn.GetFullPath().wx_str() ) );
    rc = wsl.LoadLayout( fn.GetFullPath() );
    if( !rc ) {
      log->Log( F( _T( "无法加载工作区布局 \"%s\"" ), fn.GetFullPath().wx_str() ) );
    }
  } else {
    log->Log( F( _T( "工作区布局文件不存在 \"%s\"" ), fn.GetFullPath().wx_str() ) );
  }
  return rc;
}
